<?php

namespace app\common\serve;

use app\common\logic\Logic;
use app\common\logic\SendLogic;
use think\Db;
use think\Exception;
use think\helper\Time;

/**
 * 购买
 * Class Buy
 * @package app\common\serve
 */
class Buy extends Serve
{
    /**
     * 预付购买
     * @param $params
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function prePay($params)
    {

        $uid = $params['uid'];
        $borrow_id = $params['borrow_id'];

        $money = $params['money'];
        if ($money < 1) return ['code' => 0, 'msg' => '请输入正确的金额！'];
        if (!(floor($money) == $money)) return ['code' => 0, 'msg' => '请输入正整数金额！'];

        //验证 ：
        $user = Db::name('user')->where(['id' => $uid])->find();
        if (!$user) return ['code' => 0, 'msg' => '用户不存在', 'data' => ''];

        $borrow = Db::name('borrow')->where(['id' => $borrow_id])->find();
        if (!$borrow) return ['code' => 0, 'msg' => '项目不存在', 'data' => ''];

        $pre_money = $money * ($borrow['borrow_prepay_rate'] / 100);
        $invest = [
            'invest_uid' => $params['uid'],
            'borrow_id' => $borrow_id,
            'invest_capital' => $money,
            'prepay_rate' => $borrow['borrow_prepay_rate'],
            'prepay_money' => $pre_money,
            'remain_money' => $money - $pre_money,
            'way' => $params['way'],
            'ip' => $params['ip'],
            'create_time' => $_SERVER['REQUEST_TIME'],
            'status' => 1, //冻结中
//            'audit_status' => 2//审核中
        ];

        //是否存在一笔待出售订单
        $times = Time::today();
        $invest_pid = Db::name('borrow_invest')->where(['invest_uid' => $uid, 'deadline' => [['>=', $times[0]], ['<=', $times[1]]]])->value('id');
        $invest['invest_pid'] = $invest_pid > 0 ? $invest_pid : 0;

        Db::startTrans();

        $invest_id = Db::name('borrow_invest')->insertGetId($invest);
        $money_flag = User::memberMoneyLog($uid, 5, -$pre_money, '购买' . $borrow['borrow_name'] . ', 预付款冻结中', $uid);
        $borrow_flag = Db::name('borrow')->where(['id' => $borrow_id])->update([
            'borrow_counts' => ($borrow['borrow_counts'] + 1),
            'update_time' => $_SERVER['REQUEST_TIME']
        ]);

        $msg_id = Db::name('user_msg')->insertGetId([
            'uid' => $uid,
            'title' => '预付订单成功',
            'info' => '恭喜您购买预付订单成功, 金额' . $pre_money . '元' . '，详情请查看资金记录',
            'create_time' => $_SERVER['REQUEST_TIME']
        ]);

        if ($invest_id && $borrow_flag && $money_flag && $msg_id) {
            Db::commit();

            return ['code' => 1, 'msg' => '购买预付成功，请等待财务审核.....', 'data' => ''];
        } else {
            Db::rollback();
            trace('购买失败：' . json_encode($params) . '--' . $invest_id . '-' . $money_flag . '-' . $borrow_flag . '-' . $msg_id, 'error');
            return ['code' => 0, 'msg' => '购买失败', 'data' => ''];
        }
    }

    /**
     * 确定支付
     * @param  array $params
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function readyPay($params = [])
    {
        $id = $params['id'];
        $uid = $params['uid'];

        $buy_data = Db::name('borrow_invest')->where(['id' => $id, 'invest_uid' => $uid])->find();
        if (count($buy_data) < 1) return ['code' => 0, 'msg' => '找不到购买数据', 'data' => ''];
        $borrow = Db::name('borrow')->where(['id' => $buy_data['borrow_id']])->find();

        Db::startTrans();

        $interest = self::calcDayInterest($buy_data['invest_capital'], $borrow['borrow_interest_rate'], $borrow['borrow_duration']);

        $buy_flag = Db::name('borrow_invest')->where(['id' => $id, 'invest_uid' => $uid])->update([
            'invest_interest' => $interest,
            'status' => 3, //待出售
            'deadline' => strtotime('+ ' . $borrow['borrow_duration'] . ' day', strtotime(date('Y-m-d') . ' 23:59:59')),
            'update_time' => $_SERVER['REQUEST_TIME']
        ]);

        $money_flag = User::memberMoneyLog($uid, 5, -$buy_data['remain_money'], '购买确认成功, 全款冻结', $uid);
        $money_flag2 = User::memberMoneyLog($uid, 6, $buy_data['invest_capital'], '购买下单成功，减去冻结，增加代收', $uid);
        $money_flag3 = User::memberMoneyLog($uid, 9, $interest, '计息成功，本次下单共计利息' . $interest . '元', $uid);

        $msg_id = Db::name('user_msg')->insertGetId([
            'uid' => $uid,
            'title' => '下单成功',
            'info' => '恭喜您，下单成功, 开始计算利息啦，详情请查看资金记录',
            'create_time' => $_SERVER['REQUEST_TIME']
        ]);

        if ($buy_flag && $money_flag && $money_flag2 && $money_flag3 && $msg_id) {
            Db::commit();

            //判断是否存在推荐人
            $ruid = Db::name('user')->where(['id' => intval($params['uid'])])->value('recommend_id');

            if ($ruid > 0) {
                //写入记录
                $rebate_id = $rebate_id = Db::name('user_rebate')->insertGetId([
                    'invest_id' => $id,
                    'from_uid' => $uid,
                    'invest_capital' => $buy_data['invest_capital'],
                    'invest_time' => $_SERVER['REQUEST_TIME'],

                    'to_uid' => $ruid,
                    'rebate_money' => self::calcRebateMoney($buy_data['invest_capital']),
                    'status' => 2, //未返佣
                    'create_time' => $_SERVER['REQUEST_TIME'],
                    'update_time' => $_SERVER['REQUEST_TIME']
                ]);

                //发返佣
                $flag = self::rebate([$rebate_id]);
            }

            return ['code' => 1, 'msg' => '购买成功,请到会员中心查看', 'data' => ''];
        } else {
            Db::rollback();
            trace(__METHOD__ . '-确定支付失败：' . json_encode($params) . '--' . $buy_flag . '-' . $money_flag . '-' . $money_flag2 . '-' . $msg_id, 'error');
            return ['code' => 0, 'msg' => '购买失败', 'data' => ''];
        }
    }


    /**
     * 给我的推荐人返佣
     * @param array $rebate_id
     * @return array|bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function rebate($rebate_id = [])
    {
        if (count($rebate_id) < 1) return ['code' => 0, 'msg' => '返佣ID不可为空', 'data' => ''];

        $rebate_counts = model('UserRebate')->where(['id' => $rebate_id, 'status' => 2])->count();
        if ($rebate_counts < 1) return ['code' => 0, 'msg' => '返佣记录不存在或已经返佣过，请检查', 'data' => ''];

        foreach ($rebate_id as $v) {
            self::handleRebate($v);
        }

        return true;
    }

    /**
     * 处理返佣
     * @param $rebate_id
     * @return array|bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function handleRebate($rebate_id)
    {

        $rebate_data = model('UserRebate')->where(['id' => $rebate_id, 'status' => 2])->find();
        if (!$rebate_data) return false;

        Db::startTrans();

        //用户加钱
        $money_flag = User::memberMoneyLog($rebate_data['to_uid'], 8, $rebate_data['rebate_money'], '您的推荐人下单成功，给您返佣' . $rebate_data[''] . '元');

        //平台扣钱
        $plat_money_flag = Plat::changeMoney(1, 4, -$rebate_data['rebate_money'], '发返佣扣减可用余额', $rebate_data['to_uid']);

        $msg_id = Db::name('user_msg')->insertGetId([
            'uid' => $rebate_data['to_uid'],
            'title' => '返佣到账',
            'info' => '恭喜您，您的推荐返佣已到账，共' . $rebate_data['rebate_money'] . '元，详情请查看资金记录',
            'create_time' => $_SERVER['REQUEST_TIME']
        ]);

        $rebate_flag = Db::name('user_rebate')->where(['id' => $rebate_id])->update([
            'status' => 1,
            'update_time' => time()
        ]);

        if ($money_flag && $plat_money_flag && $msg_id && $rebate_flag) {
            Db::commit();
            return true;
        } else {
            Db::rollback();
            trace(__METHOD__ . ' 返佣发放失败：' . json_encode($rebate_data) . '-' . $money_flag . '-' . $msg_id . '-' . $rebate_flag, 'error');
            return false;
        }
    }

    /**
     * 出售
     * @param array $params
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function sale($params = [])
    {
        $id = $params['id'];
        $uid = $params['uid'];

        //1、找到到期订单
        $buy_data = Db::name('borrow_invest')->where(['id' => $id, 'invest_uid' => $uid])->find();
        if (!$buy_data) return ['code' => 0, 'msg' => '找不到购买数据或者订单还未到期', 'data' => ''];

        //判断订单是否到期
//        if (strtotime(date('Y-m-d')) < ($buy_data['deadline'] - 86400)) {
//            return ['code' => 0, 'msg' => '订单还未到期，不可出售！', 'data' => ''];
//        }

//        2、判断是否购买新单
        $new_buy = Db::name('borrow_invest')->where(['invest_uid' => $uid, 'status' => 1])->count();
        if ($new_buy < 1) return ['code' => 0, 'msg' => '请先预付一笔价格为：' . $buy_data['invest_capital'] . '的订单，您方可出售。谢谢！', 'data' => ''];

        Db::startTrans();

        //3、更新账户
        $money_flag = User::memberMoneyLog($uid, 7, $buy_data['invest_capital'], '出售成功，回收本金' . $buy_data['invest_capital'] . '元', $uid);
        $money_fla2 = User::memberMoneyLog($uid, 11, $buy_data['invest_interest'], '出售成功，回收利息' . $buy_data['invest_interest'] . '元', $uid);

        //4、更新购买信息
        $invest_flag = Db::name('borrow_invest')->where(['id' => $buy_data['id']])->update([
            'receive_capital' => $buy_data['invest_capital'],
            'receive_interest' => $buy_data['invest_interest'],
            'status' => 4, //出售完成
            'sale_time' => $_SERVER['REQUEST_TIME']
        ]);

        //5、写站内信
        $msg_id = Db::name('user_msg')->insertGetId([
            'uid' => $uid,
            'title' => '出售成功',
            'info' => '恭喜您，出售成功, 本金和利息已经到账了哦，详情请查看资金记录',
            'create_time' => $_SERVER['REQUEST_TIME']
        ]);

        //6 平台减去利息
        $plat_flag = Plat::changeMoney(1, 3, -$buy_data['invest_interest'], '用户出售成功，平台支付利息' . $buy_data['invest_interest'] . '元', $uid);

        if ($money_flag && $money_fla2 && $invest_flag && $msg_id && $plat_flag) {
            Db::commit();
            return ['code' => 1, 'msg' => '出售成功', 'data' => ''];
        } else {
            Db::rollback();
            trace(__METHOD__ . '-出售失败：' . json_encode($params) . '-' . json_encode([
                    'money_flag' => $money_flag,
                    'money_fla2' => $money_fla2,
                    'invest_flag' => $invest_flag,
                    'msg_id' => $msg_id,
                    'plat_flag' => $plat_flag
                ]), 'error');
            return ['code' => 0, 'msg' => '出售失败', 'data' => ''];
        }
    }


    /**
     * 审核投资
     * @param array $params
     * @return array
     * @throws Exception
     * @throws \think\exception\PDOException
     */
    public static function auditPay($params = [])
    {
        if (!isset($params['ids']) || empty($params['ids'])) return ['code' => 0, 'msg' => '缺少ID参数', 'data' => ''];
        if (!isset($params['uid']) || empty($params['uid'])) return ['code' => 0, 'msg' => '缺少UID参数', 'data' => ''];

        $invest_db = Db::name('borrow_invest');

        $buy_data = $invest_db->field('id,invest_uid')->where(['id' => ['IN', explode(',', $params['ids'])]])->select();
        if (count($buy_data, 1) < 1) return ['code' => 0, 'msg' => '找不到购买数据', 'data' => ''];

        $counts = 0;
        $uids = [];
        $msg_db = Db::name('user_msg');
        foreach ($buy_data as $k => $v) {
            array_push($uids, $v['invest_uid']);

            Db::startTrans();

            //更新购买数据
            $flag = $invest_db->where(['id' => $v['id']])->update([
                'audit_uid' => intval($params['uid']),
                'audit_status' => intval($params['status']),
                'audit_time' => $_SERVER['REQUEST_TIME']
            ]);

            $msg_id = $msg_db->insertGetId([
                'uid' => $v['invest_uid'],
                'title' => '订单审核通过',
                'info' => '恭喜您，您的订单已经审核通过，请你尽快完成下单吧',
                'create_time' => $_SERVER['REQUEST_TIME']
            ]);

            if ($flag && $msg_id) {
                Db::commit();

                $counts++;
            } else {
                Db::rollback();

                trace(__METHOD__ . ' 批量审核失败：' . json_encode($v) . '--' . json_encode($params), 'error');
            }
        }

        if ($counts == count($buy_data)) {
            //TODO: 发短信
//            SendLogic::sendSmsByUid($uids, []);

            return ['code' => 1, 'msg' => '批量审核成功，', 'data' => ''];
        } else {
            return ['code' => 0, 'msg' => '批量审核失败', 'data' => ''];
        }

    }

    /**
     * 到期审核
     * @param $params
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function auditSale($params)
    {

        if (!isset($params['ids']) || empty($params['ids'])) return ['code' => 0, 'msg' => '缺少ID参数', 'data' => ''];
        if (!isset($params['uid']) || empty($params['uid'])) return ['code' => 0, 'msg' => '缺少UID参数', 'data' => ''];

        $invest_db = Db::name('borrow_invest');

        $buy_data = $invest_db->field('id,invest_uid')->where(['id' => ['IN', explode(',', $params['ids'])]])->select();
        if (count($buy_data, 1) < 1) return ['code' => 0, 'msg' => '找不到订单数据', 'data' => ''];

        $counts = 0;
        $uids = [];
        $msg_db = Db::name('user_msg');
        foreach ($buy_data as $k => $v) {
            array_push($uids, $v['invest_uid']);

            Db::startTrans();

            //更新购买数据
            $flag = $invest_db->where(['id' => $v['id']])->update([
                'audit_uid' => intval($params['uid']),
                'audit_status' => intval($params['status']),
                'audit_time' => $_SERVER['REQUEST_TIME']
            ]);

            $msg_id = $msg_db->insertGetId([
                'uid' => $v['invest_uid'],
                'title' => '到期审核通过',
                'info' => '恭喜您，您的到期订单已经审核通过，请你尽快出售回款吧',
                'create_time' => $_SERVER['REQUEST_TIME']
            ]);

            if ($flag && $msg_id) {
                Db::commit();

                $counts++;
            } else {
                Db::rollback();

                trace(__METHOD__ . ' 批量审核失败：' . json_encode($v) . '--' . json_encode($params), 'error');
            }
        }

        if ($counts == count($buy_data)) {
            //TODO: 发短信
//            SendLogic::sendSmsByUid($uids, []);

            return ['code' => 1, 'msg' => '批量审核成功，', 'data' => ''];
        } else {
            return ['code' => 0, 'msg' => '批量审核失败', 'data' => ''];
        }

    }

}